/*
 * sso
 */
package com.opensso.setting.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baidu.fsg.uid.UidGenerator;
import com.opensso.core.base.BaseDAO;
import com.opensso.core.base.BaseSVImpl;
import com.opensso.core.entity.Page;
import com.opensso.core.exceptions.BaseException;
import com.opensso.core.exceptions.SettingException;
import com.opensso.setting.dao.SettingDAO;
import com.opensso.setting.entity.Setting;
import com.opensso.setting.entity.SettingState;
import com.opensso.tools.RedisToolsSV;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Service("settingSV")
@CacheConfig(cacheNames = "SSO_Setting_Cache")
@Slf4j
public class SettingSVImpl extends BaseSVImpl<Setting, Long> implements SettingSV {

    @Autowired
    private SettingDAO settingDAO;

    @Resource
    private UidGenerator uidGenerator;

    @Autowired
    private RedisToolsSV redisToolsSV;

    @Override
    protected BaseDAO getBaseDAO() {
        return settingDAO;
    }

    /**
     * 保存account对象
     *
     * @param entity 实体
     * @throws BaseException
     */
    @Override
//    @CachePut(key = "#p0.id") //没有返回值的方法无法缓存
    @CacheEvict(allEntries = true)//清除所有缓存
    public void save(Setting entity) throws BaseException {
        super.save(entity);
    }

    /**
     * 加载一个对象Setting
     *
     * @param id id
     * @return Setting
     */
    @Override
//    @Cacheable(key = "T(String).valueOf(#p0)") 等于 @Cacheable(key = "T(String).valueOf(#id)"),
//    #p0表示第一个参数,#p1表示第二个参数,如果参数为对象,还可以#p0.属性,
//    @Cacheable(key = "'test'")
//    自定义常量为key值的时候,需要加上单引号   ''
    @Cacheable(key = "T(String).valueOf(#id)")
    public Setting load(java.lang.Long id) {
        if (id == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }

        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return settingDAO.load(param);
    }

    /**
     * 根据key查询 value
     *
     * @param key 设置k
     * @return value
     */
    @Override
    public String loadByK(Setting.Key key) {
        if (key == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        Setting setting = settingDAO.loadByK(key.name());
        if (setting == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Result_Not_Exist);
        }
        return setting.getV();
    }


    /**
     * 根据主键id,oldStates 共同更新 Setting 的状态到newState状态
     *
     * @param id        id
     * @param newState  新状态
     * @param oldStates 旧状态集合
     */
    @Override
    @CacheEvict(allEntries = true)
    public void updateStateById(java.lang.Long id, SettingState newState, SettingState... oldStates) {
        if (id == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        if (newState == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        if (oldStates == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        settingDAO.updateStateById(id, new Date(), newState, oldStates);
    }

    /**
     * 根据主键id 更新 Setting 的状态到另一个状态
     *
     * @param id    id
     * @param state 状态
     */
    @Override
    @CacheEvict(allEntries = true)
    public void updateById(java.lang.Long id, SettingState state) {
        if (id == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        settingDAO.updateById(id, state, new Date());
    }


    /**
     * 删除对象Setting
     *
     * @param id id
     * @return Setting
     */
    @Override
    @CacheEvict(key = "T(String).valueOf(#p0)")
    public void delete(java.lang.Long id) {
        if (id == null) {
            throw new SettingException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        settingDAO.delete(param);
    }


    /**
     * 查询Setting分页
     *
     * @param setting 对象
     * @param offset  查询开始行
     * @param limit   查询行数
     * @return List<Setting>
     */
    @Override
    @Cacheable(key = "'listSetting'")
    public List<Setting> list(Setting setting, int offset, int limit) {
        if (offset < 0) {
            offset = 0;
        }

        if (limit < 0) {
            limit = Page.limit;
        }

        Map<String, Object> map = null;
        if (setting != null) {
            map = JSON.parseObject(JSON.toJSONString(setting, SerializerFeature.WriteDateUseDateFormat));
        } else {
            map = new HashMap<>();
        }
        return settingDAO.list(map, new RowBounds(offset, limit));
    }

    @Override
    public int count(Setting setting) {
        Map<String, Object> map = null;
        if (setting != null) {
            map = JSON.parseObject(JSON.toJSONString(setting, SerializerFeature.WriteDateUseDateFormat));
        } else {
            map = new HashMap<>();
        }
        return settingDAO.count(map);
    }

    /**
     * 查询Setting分页
     *
     * @param id     id
     * @param offset 查询开始行
     * @param limit  查询行数
     * @return List<Setting>
     */
    @Override
    @Cacheable(key = "'listId'")
    public List<Setting> list(java.lang.Long id, int offset, int limit) {
        if (offset < 0) {
            offset = 0;
        }

        if (limit < 0) {
            limit = Page.limit;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return settingDAO.list(param, new RowBounds(offset, limit));
    }

    @Override
    public int count(java.lang.Long id) {
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return settingDAO.count(param);
    }

    /**
     * 测试redis工具类
     *
     * @return
     */
    public Map<String, Object> getMapFromRedis() throws Exception {
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("123", "123");
        paraMap.put("456", "456");
        paraMap.put("234", "234");
        redisToolsSV.addMap("123", paraMap);
//        redisToolsSV.hasMapKey("123", "123");
        redisToolsSV.set("777", "777大打算发发呆发发啊发啊啊");

        Setting setting = new Setting();
        setting.setId(1L);
        setting.setK("entity");
        setting.setV("entity");
        setting.setSummary("测试中文");
        redisToolsSV.set("entity", setting);
        Object entity = redisToolsSV.get("entity");
        System.out.print(entity + "\n");
        setting = JSON.parseObject(JSON.toJSONString(entity), Setting.class);
        System.out.print(setting.getId() + "\n");
        System.out.print(setting.getK() + "\n");
        System.out.print(setting.getV() + "\n");
        System.out.print(setting.getSummary() + "\n");

        List<String> testList = new ArrayList<>();
        testList.add("测试1");
        testList.add("测试2");
        testList.add("测试3");
        testList.add("测试4");
        testList.add("测试5");
        redisToolsSV.addList("testList", testList);
        testList = redisToolsSV.getList("testList");
        for (String test : testList) {
            System.out.print(test + "\n");
        }
        return redisToolsSV.getMap("123");
    }

    @CachePut(key = "#picId.concat('-').concat('byte')")
    public byte[] cachePicForByteArray(String picId) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //这里是你要读取的图像文件
//      Image image = ImageIO.read(new File("C:\\workSpaces\\background\\11111.jpg"));
        BufferedImage image = ImageIO.read(new File("C:\\workSpaces\\background\\123.jpg"));
        //这里是你要写入的文件，如果不存在这个文件，那么系统会自动创建它
        ImageIO.write(image, "png", bos);
        return bos.toByteArray();
    }


    public BufferedImage cachePicForImage(String picId) throws IOException {
        //这里是你要读取的图像文件
        BufferedImage image = ImageIO.read(new File("C:\\workSpaces\\background\\123.jpg"));
        //这里是你要写入的文件，如果不存在这个文件，那么系统会自动创建它
        ImageIO.write(image, "png", new File("C:\\dosh\\112233.png"));
        return image;
    }

}
